package com.csjbot.alicemobilecontrol.client;


import com.csjbot.alicemobilecontrol.client.nettyHandler.ClientListener;
import com.csjbot.alicemobilecontrol.client.nettyHandler.ConnectInitializer;
import com.orhanobut.logger.Logger;

import java.util.concurrent.TimeUnit;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;

/**
 * Created by huantingting on 16/6/16.
 */

public class NettyClientNew {
    private static NettyClientNew ConnectWithNetty = new NettyClientNew();

    public static NettyClientNew getInstence() {
        return ConnectWithNetty;
    }


    private NettyClientNew() {
    }

    private Channel channel = null;
    private EventLoopGroup workgroup = new NioEventLoopGroup();
    private Bootstrap bootstrap;
    private int port = 6666;
    private String ip;

    public void connect(final String ip, final ClientListener listener) {
        Logger.d("connect time");
        if (ip == null || "".equals(ip)) {
            Logger.d("connect()  ip is null");
            return;
        }
        this.ip = ip;
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    bootstrap = new Bootstrap();
                    bootstrap.group(workgroup)
                            .channel(NioSocketChannel.class)
                            .handler(new ConnectInitializer(listener));

                    //设置TCP协议的属性
                    bootstrap.option(ChannelOption.SO_KEEPALIVE, true)
                            .option(ChannelOption.TCP_NODELAY, true)
                            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000);

                    doConnect();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }


    public void disconnect() {
        if (channel != null) {
            channel.disconnect();
            channel.closeFuture();
            channel.close();
            channel = null;
        }
    }

    public void doConnect() {
        if (channel != null) {
            channel.closeFuture();
            channel.close();
            channel = null;
        }

        ChannelFuture channelFuture = null;

        try {
            channelFuture = bootstrap.connect(ip, port).sync();
            channelFuture.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture channelFuture) throws Exception {
                    if (channelFuture.isSuccess()) {
                        channel = channelFuture.channel();
//                    channel.closeFuture().sync();
                        Logger.d("Netty Client " + ip + " connect success ");
                    } else {
                        channelFuture.channel().eventLoop().schedule(new Runnable() {
                            @Override
                            public void run() {
                                doConnect();
                            }
                        }, 10, TimeUnit.SECONDS);
                        Logger.d("Netty Client " + ip + " failed ");
                    }
                }
            });
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void closeChannle() {
        if (null != channel) {
            channel.close();
        }
    }


    public void sendMessage(String data) {
        final String cmd = data + ConnectInitializer.DELIMITER;
        if (null != channel && channel.isActive()) {
            ByteBuf out = Unpooled.copiedBuffer(cmd.getBytes());
            ChannelFuture channelFuture = channel.writeAndFlush(out);
            channelFuture.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture channelFuture) throws Exception {
                    if (channelFuture.isSuccess()) {
                        Logger.i("Netty Client send " + cmd + "_isSuccess");
                    } else {
                        Logger.d("Netty Client send failed");
                    }
                }
            });
        } else {
        }
    }
}
